home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 16
/
Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso
/
Aminet
/
comm
/
term
/
term_source.lha
/
Extras
/
Source
/
term-source.lha
/
Buffer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-10-20
|
28KB
|
1,416 lines
/*
** Buffer.c
**
** Auxilary routines for text buffer/capture management.
**
** Copyright © 1990-1996 by Olaf `Olsen' Barthel
** All Rights Reserved
**
** :ts=3
*/
#ifndef _GLOBAL_H
#include "Global.h"
#endif
/* Search string window gadgets. */
enum { GAD_STRING=1000,GAD_OK,GAD_CANCEL };
/* Maximum size of an allocated line string. */
#define STRING_SIZE (1 + 255 + 1)
/* How many strings to include in a single puddle. */
#define STRING_COUNT 10
/* The number of lines the buffer will grow. */
#define BUFFER_GROW 100
/* Memory pool header. */
STATIC APTR BufferPoolHeader;
/* Word separator characters. */
STATIC BYTE WordSeparators[256] =
{
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0
};
/* AllocString(STRPTR String,LONG Len):
*
* Allocate space for a string, new pooled version.
*/
STATIC STRPTR
AllocString(STRPTR String,LONG Len)
{
STRPTR Mem;
if(Len > 255)
Len = 255;
if(Mem = (STRPTR)AsmAllocPooled(BufferPoolHeader,1 + Len + 1,SysBase))
{
*Mem++ = Len;
if(Len)
CopyMem(String,Mem,Len);
Mem[Len] = 0;
}
return(Mem);
}
/* FreeString(STRPTR String):
*
* Free the space occupied by a string, new pooled version.
*/
STATIC VOID
FreeString(STRPTR String)
{
AsmFreePooled(BufferPoolHeader,&String[-1],1 + String[-1] + 1,SysBase);
}
/* AddLine(STRPTR Line,LONG Size):
*
* Add a line to the display buffer.
*/
VOID
AddLine(STRPTR Line,LONG Size)
{
/* Are we still to update the buffer contents? */
if(!BufferClosed)
{
ULONG Signals;
BOOL Notify;
Signals = NULL;
ObtainSemaphore(&BufferSemaphore);
/* Is the buffer array initialized? */
if(BufferLines)
{
/* Check for limit. */
if(Config->CaptureConfig->MaxBufferSize && BufferSpace >= Config->CaptureConfig->MaxBufferSize)
{
LONG i;
BufferSpace -= BufferLines[0][-1];
FreeString(BufferLines[0]);
for(i = 1 ; i < MaxLines ; i++)
BufferLines[i - 1] = BufferLines[i];
Lines--;
/* Tell the buffer task to
* refresh the display.
*/
Signals = SIG_MOVEUP;
}
else
{
/* We've reached the last line in the buffer. */
if(Lines == MaxLines || ((Lines & 3) == 3 && AvailMem(MEMF_LARGEST) <= Config->CaptureConfig->BufferSafetyMemory))
{
STRPTR *MoreBuffer;
/* Allocate space for some more lines. */
if(MoreBuffer = (STRPTR *)AllocVecPooled((MaxLines + BUFFER_GROW) * sizeof(STRPTR),MEMF_ANY | MEMF_CLEAR))
{
BufferChanged = TRUE;
/* Copy the old lines to the new
* buffer.
*/
CopyMem(BufferLines,MoreBuffer,Lines * sizeof(STRPTR));
/* Free the old lines. */
FreeVecPooled(BufferLines);
/* Set the new buffer. */
MaxLines += BUFFER_GROW;
BufferLines = MoreBuffer;
}
else
{
BufferChanged = TRUE;
/* We couldn't get enough memory
* to extend the number of lines
* in the buffer, so we'll have
* to wrap the contents of the
* buffer around.
*/
if(Lines)
{
LONG i;
BufferSpace -= BufferLines[0][-1];
FreeString(BufferLines[0]);
for(i = 1 ; i < MaxLines ; i++)
BufferLines[i - 1] = BufferLines[i];
Lines--;
/* Tell the buffer task to
* refresh the display.
*/
Signals = SIG_MOVEUP;
}
}
}
}
/* Allocate a new line and copy the buffer contents
* into it.
*/
if(BufferLines[Lines] = AllocString(Line,Size))
{
BufferChanged = TRUE;
Lines++;
BufferSpace += Size;
}
Notify = TRUE;
}
else
Notify = FALSE;
ReleaseSemaphore(&BufferSemaphore);
if(Notify)
{
/* Tell the buffer tasks to update the displays. */
if(!Signals)
Signals = SIG_UPDATE;
NotifyBuffer(&BufferTaskSemaphore,&BufferInfoData,Signals);
NotifyBuffer(&ReviewTaskSemaphore,&ReviewInfoData,Signals);
}
}
}
/* DeleteBuffer():
*
* Delete buffer resources.
*/
VOID
DeleteBuffer()
{
FreeVecPooled(BufferLines);
BufferLines = NULL;
if(BufferPoolHeader)
{
AsmDeletePool(BufferPoolHeader,SysBase);
BufferPoolHeader = NULL;
}
}
/* CreateBuffer():
*
* Allocate buffer resources.
*/
BOOL
CreateBuffer()
{
if(BufferLines = (STRPTR *)AllocVecPooled(MaxLines * sizeof(STRPTR),MEMF_ANY | MEMF_CLEAR))
{
/* Create a memory pool header if possible. */
if(BufferPoolHeader = AsmCreatePool(MEMF_ANY | MEMF_PUBLIC,STRING_SIZE * STRING_COUNT,STRING_SIZE * STRING_COUNT,SysBase))
return(TRUE);
else
{
FreeVecPooled(BufferLines);
BufferLines = NULL;
}
}
return(FALSE);
}
/* FreeBuffer():
*
* Release the contents of the text buffer.
*/
VOID
FreeBuffer()
{
BOOL Notify;
ObtainSemaphore(&BufferSemaphore);
/* Free the contents of the display buffer. */
if(BufferLines)
{
APTR NewPoolHeader;
/* If a new pool header is available, free the old
* pool and replace it with the new pool.
*/
if(NewPoolHeader = AsmCreatePool(MEMF_ANY | MEMF_PUBLIC,STRING_SIZE * STRING_COUNT,STRING_SIZE * STRING_COUNT,SysBase))
{
AsmDeletePool(BufferPoolHeader,SysBase);
BufferPoolHeader = NewPoolHeader;
}
else
{
LONG i;
for(i = 0 ; i < Lines ; i++)
{
if(BufferLines[i])
FreeString(BufferLines[i]);
}
}
FreeVecPooled(BufferLines);
Lines = 0;
MaxLines = BUFFER_GROW;
BufferLines = (STRPTR *)AllocVecPooled(MaxLines * sizeof(STRPTR),MEMF_ANY | MEMF_CLEAR);
Notify = TRUE;
}
else
Notify = FALSE;
BufferSpace = 0;
BufferChanged = FALSE;
ReleaseSemaphore(&BufferSemaphore);
if(Notify)
{
NotifyBuffer(&BufferTaskSemaphore,&BufferInfoData,SIG_UPDATE);
NotifyBuffer(&ReviewTaskSemaphore,&ReviewInfoData,SIG_UPDATE);
}
}
/* DeleteSearchInfo(struct SearchInfo *Info):
*
* Free buffer allocated by CreateSearchInfo().
*/
VOID
DeleteSearchInfo(struct SearchInfo *Info)
{
FreeVecPooled(Info);
}
/* CreateSearchInfo(STRPTR Pattern):
*
* Create auxilary data required by SearchTextBuffer().
*/
struct SearchInfo *
CreateSearchInfo(STRPTR Pattern,BOOL Forward,BOOL IgnoreCase,BOOL WholeWords)
{
struct SearchInfo *Info;
/* Allocate the buffer. */
if(Info = (struct SearchInfo *)AllocVecPooled(sizeof(struct SearchInfo),MEMF_ANY|MEMF_CLEAR))
{
LONG i;
/* Determine pattern width. */
Info->PatternWidth = strlen(Pattern);
Info->IgnoreCase = IgnoreCase;
if(Info->PatternWidth == 1)
{
if(WordSeparators[Pattern[0]])
WholeWords = FALSE;
}
Info->WholeWords = WholeWords;
/* Turn the pattern into upper case characters. */
if(IgnoreCase)
{
for(i = 0 ; i <= Info->PatternWidth ; i++)
Info->Pattern[i] = ToUpper(Pattern[i]);
}
else
{
for(i = 0 ; i <= Info->PatternWidth ; i++)
Info->Pattern[i] = Pattern[i];
}
/* Fill the entire range with the maximum pattern width. */
for(i = 0 ; i < 256 ; i++)
Info->Distance[i] = Info->PatternWidth;
/* Fill in the matching distances. */
if(Forward)
{
for(i = 0 ; i < Info->PatternWidth - 1 ; i++)
Info->Distance[Info->Pattern[i]] = Info->PatternWidth - 1 - i;
}
else
{
for(i = Info->PatternWidth - 1 ; i > 0 ; i--)
Info->Distance[Info->Pattern[i]] = i;
}
/* Restart from scratch. */
Info->FoundY = -1;
Info->Forward = Forward;
}
return(Info);
}
/* SearchTextBuffer():
*
* String search function, based on the Boyer-Moore search
* algorithm.
*/
LONG
SearchTextBuffer(struct SearchInfo *Info)
{
if(BufferLines)
{
UBYTE *Distance,*Pattern;
LONG LineWidth,PatternWidth;
STRPTR Line;
LONG SearchPosition,PatternIndex,LineIndex,LastSearchPosition;
LONG i;
/* Extract the relevant data. */
Distance = Info->Distance;
Pattern = Info->Pattern;
PatternWidth = Info->PatternWidth;
if(Info->WholeWords)
{
/* Which direction are we to search? */
if(Info->IgnoreCase)
{
if(Info->Forward)
{
/* Update the search positions. */
if(Info->FoundY == -1)
{
Info->FoundX = 0;
Info->FoundY = 0;
LastSearchPosition = 0;
}
else
{
/* Proceed to the next line. */
if(!(LastSearchPosition = Info->Index))
Info->FoundY = (Info->FoundY + 1) % Lines;
}
/* Run down the buffer. */
for(i = Info->FoundY ; i < Lines ; i++)
{
Line = BufferLines[i];
/* Is there anything to search for? */
if((LineWidth = Line[-1]) >= PatternWidth)
{
/* Where are we to start searching? */
if(LastSearchPosition)
SearchPosition = LastSearchPosition;
else
SearchPosition = PatternWidth;
do
{
/* How many line characters
* match the pattern?
*/
PatternIndex = PatternWidth - 1;
LineIndex = SearchPosition - 1;
while(PatternIndex >= 0 && Pattern[PatternIndex] == ToUpper(Line[LineIndex]))
{
LineIndex--;
PatternIndex--;
}
/* Update the line search index
* for subsequent searches.
*/
SearchPosition += Distance[ToUpper(Line[SearchPosition - 1])];
/* Found the pattern? */
if(PatternIndex < 0)
{
LONG X = LineIndex + 1;
if(X)
{
if(!WordSeparators[Line[X - 1]])
continue;
else
{
if(X + PatternWidth < LineWidth && !WordSeparators[Line[X + PatternWidth]])
continue;
}
}
else
{
if(X + PatternWidth < LineWidth && !WordSeparators[Line[X + PatternWidth]])
continue;
}
/* Store the position. */
Info->FoundX = LineIndex + 1;
Info->FoundY = i;
/* Remember column to start
* next search attempt at.
*/
if(SearchPosition <= LineWidth)
Info->Index = SearchPosition;
else
Info->Index = 0;
return(i);
}
}
while(SearchPosition <= LineWidth);
}
/* Reset search column. */
LastSearchPosition = 0;
}
}
else
{
/* Update the search positions. */
if(Info->FoundY == -1)
{
Info->FoundX = 0;
Info->FoundY = Lines - 1;
LastSearchPosition = 0;
}
else
{
if((LastSearchPosition = Info->Index) < 1)
{
if(Info->FoundY)
Info->FoundY--;
else
Info->FoundY = Lines - 1;
}
}
/* Run down the buffer. */
for(i = Info->FoundY ; i >= 0 ; i--)
{
Line = BufferLines[i];
/* Is there anything to search for? */
if((LineWidth = Line[-1]) >= PatternWidth)
{
/* Cast the magic spell of Boyer-Moore... */
if(LastSearchPosition < 1)
SearchPosition = LineWidth - (PatternWidth - 1);
else
SearchPosition = LastSearchPosition;
do
{
PatternIndex = 0;
LineIndex = SearchPosition - 1;
while(PatternIndex < PatternWidth && Pattern[PatternIndex] == ToUpper(Line[LineIndex]))
{
LineIndex++;
PatternIndex++;
}
SearchPosition -= Distance[ToUpper(Line[SearchPosition - 1])];
if(PatternIndex == PatternWidth)
{
LONG X = LineIndex - PatternWidth;
if(X)
{
if(!WordSeparators[Line[X - 1]])
continue;
else
{
if(X + PatternWidth < LineWidth && !WordSeparators[Line[X + PatternWidth]])
continue;
}
}
else
{
if(X + PatternWidth < LineWidth && !WordSeparators[Line[X + PatternWidth]])
continue;
}
Info->FoundX = LineIndex - PatternWidth;
Info->FoundY = i;
Info->Index = SearchPosition;
return(i);
}
}
while(SearchPosition > 0);
}
LastSearchPosition = 0;
}
}
}
else
{
if(Info->Forward)
{
/* Update the search positions. */
if(Info->FoundY == -1)
{
Info->FoundX = 0;
Info->FoundY = 0;
LastSearchPosition = 0;
}
else
{
/* Proceed to the next line. */
if(!(LastSearchPosition = Info->Index))
Info->FoundY = (Info->FoundY + 1) % Lines;
}
/* Run down the buffer. */
for(i = Info->FoundY ; i < Lines ; i++)
{
Line = BufferLines[i];
/* Is there anything to search for? */
if((LineWidth = Line[-1]) >= PatternWidth)
{
/* Where are we to start searching? */
if(LastSearchPosition)
SearchPosition = LastSearchPosition;
else
SearchPosition = PatternWidth;
do
{
/* How many line characters
* match the pattern?
*/
PatternIndex = PatternWidth - 1;
LineIndex = SearchPosition - 1;
while(PatternIndex >= 0 && Pattern[PatternIndex] == Line[LineIndex])
{
LineIndex--;
PatternIndex--;
}
/* Update the line search index
* for subsequent searches.
*/
SearchPosition += Distance[Line[SearchPosition - 1]];
/* Found the pattern? */
if(PatternIndex < 0)
{
LONG X = LineIndex + 1;
if(X)
{
if(!WordSeparators[Line[X - 1]])
continue;
else
{
if(X + PatternWidth < LineWidth && !WordSeparators[Line[X + PatternWidth]])
continue;
}
}
else
{
if(X + PatternWidth < LineWidth && !WordSeparators[Line[X + PatternWidth]])
continue;
}
/* Store the position. */
Info->FoundX = LineIndex + 1;
Info->FoundY = i;
/* Remember column to start
* next search attempt at.
*/
if(SearchPosition <= LineWidth)
Info->Index = SearchPosition;
else
Info->Index = 0;
return(i);
}
}
while(SearchPosition <= LineWidth);
}
/* Reset search column. */
LastSearchPosition = 0;
}
}
else
{
/* Update the search positions. */
if(Info->FoundY == -1)
{
Info->FoundX = 0;
Info->FoundY = Lines - 1;
LastSearchPosition = 0;
}
else
{
if((LastSearchPosition = Info->Index) < 1)
{
if(Info->FoundY)
Info->FoundY--;
else
Info->FoundY = Lines - 1;
}
}
/* Run down the buffer. */
for(i = Info->FoundY ; i >= 0 ; i--)
{
Line = BufferLines[i];
/* Is there anything to search for? */
if((LineWidth = Line[-1]) >= PatternWidth)
{
/* Cast the magic spell of Boyer-Moore... */
if(LastSearchPosition < 1)
SearchPosition = LineWidth - (PatternWidth - 1);
else
SearchPosition = LastSearchPosition;
do
{
PatternIndex = 0;
LineIndex = SearchPosition - 1;
while(PatternIndex < PatternWidth && Pattern[PatternIndex] == Line[LineIndex])
{
LineIndex++;
PatternIndex++;
}
SearchPosition -= Distance[Line[SearchPosition - 1]];
if(PatternIndex == PatternWidth)
{
LONG X = LineIndex - PatternWidth;
if(X)
{
if(!WordSeparators[Line[X - 1]])
continue;
else
{
if(X + PatternWidth < LineWidth && !WordSeparators[Line[X + PatternWidth]])
continue;
}
}
else
{
if(X + PatternWidth < LineWidth && !WordSeparators[Line[X + PatternWidth]])
continue;
}
Info->FoundX = LineIndex - PatternWidth;
Info->FoundY = i;
Info->Index = SearchPosition;
return(i);
}
}
while(SearchPosition > 0);
}
LastSearchPosition = 0;
}
}
}
}
else
{
/* Which direction are we to search? */
if(Info->IgnoreCase)
{
if(Info->Forward)
{
/* Update the search positions. */
if(Info->FoundY == -1)
{
Info->FoundX = 0;
Info->FoundY = 0;
LastSearchPosition = 0;
}
else
{
/* Proceed to the next line. */
if(!(LastSearchPosition = Info->Index))
Info->FoundY = (Info->FoundY + 1) % Lines;
}
/* Run down the buffer. */
for(i = Info->FoundY ; i < Lines ; i++)
{
Line = BufferLines[i];
/* Is there anything to search for? */
if((LineWidth = Line[-1]) >= PatternWidth)
{
/* Where are we to start searching? */
if(LastSearchPosition)
SearchPosition = LastSearchPosition;
else
SearchPosition = PatternWidth;
do
{
/* How many line characters
* match the pattern?
*/
PatternIndex = PatternWidth - 1;
LineIndex = SearchPosition - 1;
while(PatternIndex >= 0 && Pattern[PatternIndex] == ToUpper(Line[LineIndex]))
{
LineIndex--;
PatternIndex--;
}
/* Update the line search index
* for subsequent searches.
*/
SearchPosition += Distance[ToUpper(Line[SearchPosition - 1])];
/* Found the pattern? */
if(PatternIndex < 0)
{
/* Store the position. */
Info->FoundX = LineIndex + 1;
Info->FoundY = i;
/* Remember column to start
* next search attempt at.
*/
if(SearchPosition <= LineWidth)
Info->Index = SearchPosition;
else
Info->Index = 0;
return(i);
}
}
while(SearchPosition <= LineWidth);
}
/* Reset search column. */
LastSearchPosition = 0;
}
}
else
{
/* Update the search positions. */
if(Info->FoundY == -1)
{
Info->FoundX = 0;
Info->FoundY = Lines - 1;
LastSearchPosition = 0;
}
else
{
if((LastSearchPosition = Info->Index) < 1)
{
if(Info->FoundY)
Info->FoundY--;
else
Info->FoundY = Lines - 1;
}
}
/* Run down the buffer. */
for(i = Info->FoundY ; i >= 0 ; i--)
{
Line = BufferLines[i];
/* Is there anything to search for? */
if((LineWidth = Line[-1]) >= PatternWidth)
{
/* Cast the magic spell of Boyer-Moore... */
if(LastSearchPosition < 1)
SearchPosition = LineWidth - (PatternWidth - 1);
else
SearchPosition = LastSearchPosition;
do
{
PatternIndex = 0;
LineIndex = SearchPosition - 1;
while(PatternIndex < PatternWidth && Pattern[PatternIndex] == ToUpper(Line[LineIndex]))
{
LineIndex++;
PatternIndex++;
}
SearchPosition -= Distance[ToUpper(Line[SearchPosition - 1])];
if(PatternIndex == PatternWidth)
{
Info->FoundX = LineIndex - PatternWidth;
Info->FoundY = i;
Info->Index = SearchPosition;
return(i);
}
}
while(SearchPosition > 0);
}
LastSearchPosition = 0;
}
}
}
else
{
if(Info->Forward)
{
/* Update the search positions. */
if(Info->FoundY == -1)
{
Info->FoundX = 0;
Info->FoundY = 0;
LastSearchPosition = 0;
}
else
{
/* Proceed to the next line. */
if(!(LastSearchPosition = Info->Index))
Info->FoundY = (Info->FoundY + 1) % Lines;
}
/* Run down the buffer. */
for(i = Info->FoundY ; i < Lines ; i++)
{
Line = BufferLines[i];
/* Is there anything to search for? */
if((LineWidth = Line[-1]) >= PatternWidth)
{
/* Where are we to start searching? */
if(LastSearchPosition)
SearchPosition = LastSearchPosition;
else
SearchPosition = PatternWidth;
do
{
/* How many line characters
* match the pattern?
*/
PatternIndex = PatternWidth - 1;
LineIndex = SearchPosition - 1;
while(PatternIndex >= 0 && Pattern[PatternIndex] == Line[LineIndex])
{
LineIndex--;
PatternIndex--;
}
/* Update the line search index
* for subsequent searches.
*/
SearchPosition += Distance[Line[SearchPosition - 1]];
/* Found the pattern? */
if(PatternIndex < 0)
{
/* Store the position. */
Info->FoundX = LineIndex + 1;
Info->FoundY = i;
/* Remember column to start
* next search attempt at.
*/
if(SearchPosition <= LineWidth)
Info->Index = SearchPosition;
else
Info->Index = 0;
return(i);
}
}
while(SearchPosition <= LineWidth);
}
/* Reset search column. */
LastSearchPosition = 0;
}
}
else
{
/* Update the search positions. */
if(Info->FoundY == -1)
{
Info->FoundX = 0;
Info->FoundY = Lines - 1;
LastSearchPosition = 0;
}
else
{
if((LastSearchPosition = Info->Index) < 1)
{
if(Info->FoundY)
Info->FoundY--;
else
Info->FoundY = Lines - 1;
}
}
/* Run down the buffer. */
for(i = Info->FoundY ; i >= 0 ; i--)
{
Line = BufferLines[i];
/* Is there anything to search for? */
if((LineWidth = Line[-1]) >= PatternWidth)
{
/* Cast the magic spell of Boyer-Moore... */
if(LastSearchPosition < 1)
SearchPosition = LineWidth - (PatternWidth - 1);
else
SearchPosition = LastSearchPosition;
do
{
PatternIndex = 0;
LineIndex = SearchPosition - 1;
while(PatternIndex < PatternWidth && Pattern[PatternIndex] == Line[LineIndex])
{
LineIndex++;
PatternIndex++;
}
SearchPosition -= Distance[Line[SearchPosition - 1]];
if(PatternIndex == PatternWidth)
{
Info->FoundX = LineIndex - PatternWidth;
Info->FoundY = i;
Info->Index = SearchPosition;
return(i);
}
}
while(SearchPosition > 0);
}
LastSearchPosition = 0;
}
}
}
}
}
return(-1);
}
STATIC ULONG SAVE_DS ASM
HistoryFunc(REG(a0) struct Hook *Hook,REG(a2) APTR Unused,REG(a1) STRPTR NewString)
{
struct List *List = (struct List *)Hook->h_Data;
if(NewString)
{
struct Node *Node = CreateNode(NewString);
if(Node)
AddTail(List,Node);
else
return(FALSE);
}
else
{
struct Node *Node = RemHead(List);
FreeVecPooled(Node);
}
return(TRUE);
}
BOOL
HandleSearchMessage(struct SearchContext *Context,struct IntuiMessage **MessagePtr)
{
struct IntuiMessage *Message;
BOOL Done;
Done = FALSE;
if(Message = GT_FilterIMsg(*MessagePtr))
{
ULONG MsgClass,MsgQualifier;
struct Gadget *MsgGadget;
UWORD MsgCode;
MsgClass = Message->Class;
MsgQualifier = Message->Qualifier;
MsgGadget = (struct Gadget *)Message->IAddress;
MsgCode = Message->Code;
LT_HandleInput(Context->SearchHandle,MsgQualifier,&MsgClass,&MsgCode,&MsgGadget);
if(MsgClass == IDCMP_CLOSEWINDOW)
Done = TRUE;
if(MsgClass == IDCMP_GADGETUP)
{
switch(MsgGadget->GadgetID)
{
case GAD_STRING:
if(MsgCode == '\r')
{
if(Context->LocalBuffer[0])
{
strcpy(Context->Buffer,Context->LocalBuffer);
Context->Ok = TRUE;
LT_PressButton(Context->SearchHandle,GAD_OK);
}
else
LT_PressButton(Context->SearchHandle,GAD_CANCEL);
Done = TRUE;
}
break;
case GAD_OK:
LT_UpdateStrings(Context->SearchHandle);
if(Context->LocalBuffer[0])
{
strcpy(Context->Buffer,Context->LocalBuffer);
Context->Ok = TRUE;
}
Done = TRUE;
break;
case GAD_CANCEL:
Done = TRUE;
break;
}
}
GT_PostFilterIMsg(Message);
}
ReplyMsg((struct Message *)*MessagePtr);
*MessagePtr = NULL;
return(Done);
}
VOID
DeleteSearchContext(struct SearchContext *Context)
{
if(Context)
{
LT_DeleteHandle(Context->SearchHandle);
FreeVecPooled(Context);
}
}
struct SearchContext *
CreateSearchContext(struct Window *ParentWindow,STRPTR Buffer,struct Hook *HistoryHook,struct List *HistoryHookList,BOOL *Forward,BOOL *IgnoreCase,BOOL *WholeWords)
{
struct SearchContext *Context;
if(Context = (struct SearchContext *)AllocVecPooled(sizeof(struct SearchContext),MEMF_ANY | MEMF_CLEAR))
{
struct LayoutHandle *Handle;
Context->Buffer = Buffer;
InitHook(HistoryHook,(HOOKFUNC)HistoryFunc,HistoryHookList);
if(Handle = LT_CreateHandleTags(ParentWindow->WScreen,
LAHN_LocaleHook, &LocaleHook,
TAG_DONE))
{
struct Window *Window;
LT_New(Handle,
LA_Type, VERTICAL_KIND,
TAG_DONE);
{
LT_New(Handle,
LA_Type, HORIZONTAL_KIND,
TAG_DONE);
{
LT_New(Handle,
LA_Type, VERTICAL_KIND,
TAG_DONE);
{
LT_New(Handle,
LA_Type, STRING_KIND,
LA_LabelID, MSG_V36_0788,
LA_STRPTR, Context->LocalBuffer,
LA_Chars, 30,
LA_ID, GAD_STRING,
LAST_HistoryLines, MAX(Config->CaptureConfig->SearchHistory,1),
LAST_HistoryHook, HistoryHook,
GTST_MaxChars, sizeof(Context->LocalBuffer) - 1,
TAG_DONE);
LT_EndGroup(Handle);
}
LT_New(Handle,
LA_Type, VERTICAL_KIND,
TAG_DONE);
{
LT_New(Handle,
LA_Type,YBAR_KIND,
TAG_DONE);
LT_EndGroup(Handle);
}
LT_New(Handle,
LA_Type, VERTICAL_KIND,
TAG_DONE);
{
LT_New(Handle,
LA_Type, CHECKBOX_KIND,
LA_LabelID, MSG_TERMBUFFER_SEARCH_FORWARD_TXT,
LA_BYTE, Forward,
TAG_DONE);
LT_New(Handle,
LA_Type, CHECKBOX_KIND,
LA_LabelID, MSG_TEXTBUFFER_IGNORE_CASE_GAD,
LA_BYTE, IgnoreCase,
TAG_DONE);
LT_New(Handle,
LA_Type, CHECKBOX_KIND,
LA_LabelID, MSG_SEARCH_ONLY_WHOLE_WORDS_TXT,
LA_BYTE, WholeWords,
TAG_DONE);
LT_EndGroup(Handle);
}
LT_EndGroup(Handle);
}
LT_New(Handle,
LA_Type, VERTICAL_KIND,
TAG_DONE);
{
LT_New(Handle,
LA_Type, XBAR_KIND,
LAXB_FullSize, TRUE,
TAG_DONE);
LT_EndGroup(Handle);
}
LT_New(Handle,LA_Type,HORIZONTAL_KIND,
LAGR_SameSize, TRUE,
LAGR_Spread, TRUE,
TAG_DONE);
{
LT_New(Handle,
LA_Type, BUTTON_KIND,
LA_LabelID, MSG_TERMXPR_OKAY_GAD,
LA_ID, GAD_OK,
LABT_ReturnKey, TRUE,
LABT_ExtraFat, TRUE,
TAG_DONE);
LT_New(Handle,
LA_Type, BUTTON_KIND,
LA_LabelID, MSG_GLOBAL_CANCEL_GAD,
LA_ID, GAD_CANCEL,
LABT_EscKey, TRUE,
LABT_ExtraFat, TRUE,
TAG_DONE);
LT_EndGroup(Handle);
}
LT_EndGroup(Handle);
}
if(Window = LT_Build(Handle,
LAWN_TitleID, MSG_TERMBUFFER_ENTER_SEARCH_STRING_TXT,
LAWN_IDCMP, IDCMP_CLOSEWINDOW,
LAWN_HelpHook, &GuideHook,
LAWN_Parent, ParentWindow,
LAWN_UserPort, ParentWindow->UserPort,
WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE,
WA_DragBar, TRUE,
WA_RMBTrap, TRUE,
WA_Activate, TRUE,
WA_SimpleRefresh, TRUE,
TAG_DONE))
{
LT_Activate(Handle,GAD_STRING);
Context->SearchHandle = Handle;
Context->SearchWindow = Window;
return(Context);
}
}
FreeVecPooled(Context);
}
return(NULL);
}